package com.yu.yupicture.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.bean.copier.CopyOptions;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yu.yupicture.Untils.ThrowUntil;
import com.yu.yupicture.exception.ErrorCode;
import com.yu.yupicture.exception.biusnessException;
import com.yu.yupicture.mapper.SpaceUserMapper;
import com.yu.yupicture.model.domain.dto.space.SpaceQueryRequest;
import com.yu.yupicture.model.domain.dto.spaceUser.SpaceUserAddRequest;
import com.yu.yupicture.model.domain.dto.spaceUser.SpaceUserEditRequest;
import com.yu.yupicture.model.domain.entry.Space;
import com.yu.yupicture.model.domain.entry.SpaceUser;
import com.yu.yupicture.model.domain.entry.User;
import com.yu.yupicture.model.domain.vo.SpaceUserVO;
import com.yu.yupicture.model.domain.vo.SpaceVO;
import com.yu.yupicture.model.domain.vo.UserVo;
import com.yu.yupicture.model.enums.SpaceRoleEnum;
import com.yu.yupicture.model.enums.SpaceTypeEnum;
import com.yu.yupicture.service.SpaceService;
import com.yu.yupicture.service.SpaceUserService;
import com.yu.yupicture.service.UserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * @author Li Shuokang
 * @description 针对表【space_user(空间用户关联)】的数据库操作Service实现
 * @createDate 2025-08-06 12:09:43
 */


@Slf4j
@Service
@RequiredArgsConstructor
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser>
        implements SpaceUserService {
    private final UserService userService;
    private final SpaceService spaceService;

    /**
     * 删除成员
     *
     * @param id
     * @return
     */
    @Override
    public boolean deleteSpaceUserById(Long id, User loginUser) {
        //查询该用户所在团队空间
        Space space = spaceService.getOne(new QueryWrapper<Space>().eq("userId", loginUser.getId()).eq("spaceType", SpaceTypeEnum.TEAM.getValue()));
        if (space == null) {
            throw new biusnessException(ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
        int i = this.getBaseMapper().delete(new QueryWrapper<SpaceUser>().eq("userId", id).eq("spaceId", space.getId()));
        return i > 0;
    }

    /**
     * 修改成员角色
     *
     * @param spaceUserEditRequest
     * @return
     */
    @Override
    public boolean updateSpaceUser(SpaceUserEditRequest spaceUserEditRequest, User loginUser) {
        //校验参数
        ThrowUntil.throwIf(spaceUserEditRequest == null || loginUser == null, ErrorCode.PARAMS_ERROR, "参数错误");
        //todo 校验权限

        //查询该用户所在团队空间
        Space space = spaceService.getOne(new QueryWrapper<Space>().eq("userId", loginUser.getId()).eq("spaceType", SpaceTypeEnum.TEAM.getValue()));
        if (space == null) {
            throw new biusnessException(ErrorCode.NOT_FOUND_ERROR, "空间不存在");
        }
        SpaceUser spaceUser = new SpaceUser();
        BeanUtil.copyProperties(spaceUserEditRequest, spaceUser);
        boolean b = this.update(spaceUser,new QueryWrapper<SpaceUser>().eq("spaceId", space.getId()).eq("userId", spaceUserEditRequest.getId()));
        ThrowUntil.throwIf(!b, ErrorCode.OPERATION_ERROR, "修改成员失败");
        return true;
    }

    /**
     * 新增成员 -管理员
     *
     * @param spaceUserAddRequest
     * @param loginUser
     * @return
     */
    @Override
    public void addSpaceUser(SpaceUserAddRequest spaceUserAddRequest, User loginUser) {
        //校验参数
        ThrowUntil.throwIf(spaceUserAddRequest == null || loginUser == null, ErrorCode.PARAMS_ERROR);

        if (spaceUserAddRequest.getSpaceRole() == null) {
            spaceUserAddRequest.setSpaceRole(SpaceRoleEnum.VIEWER.getValue());
        }
        //todo 校验权限
        //判断用户是否存在
        Long loginUserId = loginUser.getId();
        Long spaceId = spaceUserAddRequest.getSpaceId();
        Long currUserId = spaceUserAddRequest.getUserId();
        SpaceUser copySpaceUser = new SpaceUser();
        BeanUtil.copyProperties(spaceUserAddRequest, copySpaceUser);
        this.checkUserAndSpace(copySpaceUser, true);
        //判断用户是否已加入空间
        boolean exists = this.getBaseMapper().exists(new LambdaQueryWrapper<SpaceUser>().eq(SpaceUser::getUserId, currUserId).eq(SpaceUser::getSpaceId, spaceId));
        if (exists) {
            throw new biusnessException(ErrorCode.OPERATION_ERROR, "用户已加入空间");
        }

        boolean save = this.save(copySpaceUser);
        if (!save) {
            throw new biusnessException(ErrorCode.OPERATION_ERROR, "添加成员失败");
        }
    }

    /**
     * 校验
     */
    @Override
    public void checkUserAndSpace(SpaceUser spaceUser, boolean add) {
        Long spaceId = spaceUser.getSpaceId();
        Long userId = spaceUser.getUserId();
        String spaceRole = spaceUser.getSpaceRole();

        if (add) {//添加成员
            User user = userService.getById(userId);
            ThrowUntil.throwIf(user == null, ErrorCode.NOT_FOUND_ERROR, "用户不存在");
            Space space = spaceService.getSpaceById(spaceId);
            ThrowUntil.throwIf(space == null, ErrorCode.NOT_FOUND_ERROR, "空间不存在");
            //判断用户是否已加入空间
            boolean exists = this.getBaseMapper().exists(new LambdaQueryWrapper<SpaceUser>().eq(SpaceUser::getUserId, userId).eq(SpaceUser::getSpaceId, spaceId));
            if (exists) {
                throw new biusnessException(ErrorCode.OPERATION_ERROR, "用户已加入空间");
            }
        } else {//修改成员
            SpaceRoleEnum enumByValue = SpaceRoleEnum.getEnumByValue(spaceRole);
            ThrowUntil.throwIf(enumByValue == null, ErrorCode.PARAMS_ERROR, "空间角色错误");
        }

    }

    /**
     * 获取空间成员列表
     *
     * @param spaceQueryRequest
     * @return
     */
    @Override
    public List<SpaceUserVO> getSpaceUserList(SpaceQueryRequest spaceQueryRequest) {
        ThrowUntil.throwIf(spaceQueryRequest == null, ErrorCode.PARAMS_ERROR, "参数错误");
        QueryWrapper<SpaceUser> queryWrapper = getQueryWrapper(spaceQueryRequest);
        List<SpaceUser> spaceList = this.list(queryWrapper);
        return this.spaceUserListToVo(spaceList);
    }

    private static QueryWrapper<SpaceUser> getQueryWrapper(SpaceQueryRequest spaceQueryRequest) {
        Long id = spaceQueryRequest.getId();
        Long userId = spaceQueryRequest.getUserId();
        String spaceName = spaceQueryRequest.getSpaceName();
        Integer spaceLevel = spaceQueryRequest.getSpaceLevel();
        Integer spaceType = spaceQueryRequest.getSpaceType();


        QueryWrapper<SpaceUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNotBlank(spaceName),"spaceName", spaceName);
        queryWrapper.eq(id != null, "id", id);
        queryWrapper.eq(userId != null, "userId", userId);
        return queryWrapper;
    }

    /**
     * 获取空间成员VO
     *
     * @param spaceUser
     * @return
     */
    @Override
    public SpaceUserVO SpaceUserToVo(SpaceUser spaceUser) {
        Long userId = spaceUser.getUserId();
        //获取用户信息
        UserVo userVo = userService.getUserVo(userId);
        SpaceVO spaceVO = spaceService.getSpaceVoById(spaceUser.getSpaceId());
        SpaceUserVO spaceUserVO = new SpaceUserVO();
        BeanUtil.copyProperties(spaceUser, spaceUserVO);
        spaceUserVO.setUser(userVo);
        spaceUserVO.setSpace(spaceVO);
        log.info("spaceUserVO:{}", spaceUserVO);
        return spaceUserVO;
    }

    /**
     * 获取空间成员VO列表
     *
     * @param spaceUserList
     * @return
     */
    @Override
    public List<SpaceUserVO> spaceUserListToVo(List<SpaceUser> spaceUserList) {
        return spaceUserList.stream().map(this::SpaceUserToVo).toList();
    }

    /**
     * 获取单个空间成员信息
     * @param spaceQueryRequest
     * @return
     */
    @Override
    public SpaceUserVO getSpaceUser(SpaceQueryRequest spaceQueryRequest) {
        ThrowUntil.throwIf(spaceQueryRequest == null, ErrorCode.PARAMS_ERROR, "参数错误");
        QueryWrapper<SpaceUser> queryWrapper = getQueryWrapper(spaceQueryRequest);
        SpaceUser spaceUser = this.getOne(queryWrapper);
        return SpaceUserToVo(spaceUser);
    }

}




